Example A-7 : Program That Explores the Address Space
#include <stddef.h> /* for standard malloc(3C) */ #include <unistd.h> /* for sbrk(2) */ #include <stdio.h> /* for printf */ #include <sys/types.h> /* for __psint_t */ /* include <sys/stat.h> */ #include <sys/fcntl.h> /* for O_RDWR */ #include <sys/mman.h> /* for mmap(2) */ #define DISPLAY(v,t) {printf("%s:\t%0lx\n",t,(__psint_t)v);} int main() { /* || Get a mask that truncates an address to a page boundary. */ __psint_t psize = getpagesize(); __psint_t pmask = ~(psize-1); /* || Get a file descriptor for the nothing device. || Use that FD to map two segments of memory containing 00. */ int zero = open("/dev/zero",O_RDWR); void * zmap1 = mmap(0,16384,PROT_WRITE,MAP_SHARED,zero,0); void * zmap2 = mmap(0,16384,PROT_WRITE,MAP_SHARED,zero,0); /* || Map one segment at a designated address reserved for || user maps by the MIPS ABI. */ void * abi_map = (char *)mmap((void *)0x30040000L,16384, PROT_WRITE,MAP_SHARED+MAP_FIXED,zero, 0); /* || Get the address of this program. */ char * poke = (char *)((__psint_t)main); /* || Get some program addresses supplied by ld(1), but note || the warnings in end(3C) -- these addresses "have no standard || definition" when multiple text/data segments exist. */ extern int _ftext[]; void * ld_ftext = (void *)_ftext; extern int _etext[]; void * ld_etext = (void *)_etext; extern int _fdata[]; void * ld_fdata = (void *)_fdata; extern int _edata[]; void * ld_edata = (void *)_edata; extern int _fbss[]; void * ld_fbss = (void *)_fbss; extern int _end[]; void * ld_end = (void *)_end; /* || Get the address of some code in the libc DSO. */ void * libc_adr = (void *)fprintf; /* || Get the current start and end of the heap. */ void * malloc_adr = (void *)malloc((size_t)256); void * brk_adr = sbrk(0); /* || Get the address of an item in our stack space. */ void * stack_adr = (void *)&psize; /* || Display all the above. */ DISPLAY(psize,"Page size") DISPLAY(zmap1,"Mapped segment 1") DISPLAY(zmap2,"Mapped segment 2") DISPLAY(abi_map,"ABI mapped segment") DISPLAY(ld_ftext,"Text starts") DISPLAY(ld_etext,"Text ends") DISPLAY(ld_fdata,"Initialized data starts") DISPLAY(ld_edata,"Initialized data ends") DISPLAY(ld_fbss,"Uninitialized starts") DISPLAY(ld_end,"Uninitialized ends") DISPLAY(malloc_adr,"Heap data starts") DISPLAY(brk_adr,"Heap data ends") DISPLAY(stack_adr,"Stack data") DISPLAY(libc_adr,"Spot in one DSO") /* || See if we can get away with patching our own text. */ if (!mprotect((void *)(pmask&(__psint_t)poke),psize,PROT_WRITE+PROT_EXEC)) { poke[0] = poke[0]; printf("I wrote into program text\n"); } else { perror("mprotect(text)"); } }